import re
import time
import requests
import multiprocessing
# import asyncio
import json
from requests_toolbelt import MultipartEncoder
from frame_work.type_file import (
    highQualitySource,
    EnterType
)
from frame_work.setting import *
from frame_work.logger import Logger
from frame_work.util import (
    change_user_account_status,
    get_binded_shop_list,
    bind_shop,
    get_seller_level,
    get_order_url,
    assert_result_dict
)
from frame_work.login import PcLogin
from workspace.shikee.chuji.pay import PayQuantity
# from frame_work.d_redis import MyRedis
from frame_work.yaml_file import YAML
from frame_work.release_util import high_quality_release

logger = Logger(__name__).get_logger()


class Activity(object):

    def __init__(self, uname):
        self.uname = uname
        self.session = self.get_session()
        self.pay = PayQuantity(self.session)
        self.tids = []
        self.nums = 0
        self.yaml = YAML(os.path.join(base_Dir, 'data', 'data.yaml'))

    def get_session(self):
        """
        :return:返回登录session
        """
        login = PcLogin(self.uname)
        # login = PcLogin('user0637')
        login.pc_login()
        return login.get_session()

    def get_html(self):
        """
        请求一个页面，在响应中获取比如：token，shopId等
        :return: html
        """
        url = self.yaml.get_data("token").get('url')
        html = self.session.get(url).text
        return html

    def get_token(self):
        """
        从html中通过正则表达式获取token
        :return:token
        """
        complex_value = 'name="token" value="(.*?)"'
        html = self.get_html()
        token = re.findall(complex_value, html)
        try:
            token = token[0]
            logger.debug('获取token值 => %s ...' % token)
        except (IndexError, KeyError) as e:
            logger.debug("获取token出错")
            return False
        else:
            return token

    def get_pic(self, num):
        """
        发布活动中会含有上传图片的操作，此函数在作用post一张图片到图片服务器，获取tmp address类似：tmp/2019/08/20/08500820924072552490.jpg
        :param num:第几张图片
        :return:pic_addr
        """
        shikee_cookies = self.session.cookies.get(
            'shikee')  # 获取用户cookies中的shikee部分
        yaml_data = self.yaml.get_data("echo_tmp_pic_address")
        yaml_data.get('data').update({
            'id': 'WU_FILE_' + str(num),  # num:发布活动页面有多个上传图片地方,用于区别
            'Filedata': ('filename', open(os.path.join(image_Path, '精品试用活动.png'), 'rb'), 'image/png')
        })
        m = MultipartEncoder(
            fields=yaml_data.get('data')
        )
        r = requests.post(url=yaml_data.get('url') + '/1?swf_upload_cookie=' + shikee_cookies, data=m,
                          headers={'Content-Type': m.content_type})
        pic_addr = r.text
        return pic_addr

    def echo_task(source):
        """
        根据来源,输出增值任务数组类型
        :param source:
        :return:
        """
        if source in (1, 2):
            return [4, 8, 16, 32, 64, 128]
        elif source in (5, 12, 15):
            return [8, 16, 32, 64, 128]
        elif source == 13:
            return [8, 16, 64, 128]
        elif source == 8:
            return [8, 16, 32, 128]
        elif source == 14:
            return [8, 16, 32, 64]

    @staticmethod
    def echo_source():
        """
        列出活动来源,用户自己选择
        :return:source
        """
        for index, i in enumerate(highQualitySource.source.value, start=1):
            print(index, ''.join(list(i.keys())))
        try:
            choise_source = int(
                input("请选择活动来源选项(可多选，直接输入对应序号(例如:123)):\t\n---->  "))
        except BaseException as e:
            logger.error('输入选项错误，请选择对应序号')
        else:
            # 最终确定以数组形式的来源，例如[1,2,16,32]
            source = [highQualitySource.source.value[int(
                i) - 1].values()for i in str(choise_source).strip()]
            source_list = list(map(lambda x: list(x)[0], source))
            return source_list

    @staticmethod
    def echo_enter_type():
        """
        批量进店方式写死（目前只支持关键词/扫码下单/直链）
        :return:enter_type
        """
        return [EnterType['关键词搜索下单'].value,
                EnterType['扫码下单'].value, EnterType['APP直链下单'].value]

    def release_basic(self, *args, **kwargs):
        """
        发布封装
        :param args:
        :param kwargs:
        :return:
        """
        value = get_seller_level(self.uname)
        level = value[0].get("level")
        if level not in [4, 11, 12]:
            logger.info("非紫金/王者/星耀vip不能发布精品试用")
            return
        source = kwargs.get("source")
        source_cn = highQualitySource(source).name  # 枚举类通过value反向获取name
        source_cn = '淘特' if source_cn == '淘宝特价版' else source_cn
        value = get_binded_shop_list(self.uname, source_cn)
        if not value:
            bind_shop(source_cn, self.uname)
            value = get_binded_shop_list(self.uname, source_cn)
        enter_type = kwargs.get("enter_type")
        title = source_cn + '_精品深度' + '_自选进店_刘'
        url, post_data, header = high_quality_release(
            enter_type=kwargs.get("enter_type"),
            qr_search_pic=json.loads(self.get_pic(2)).get('data'),
            qr_order_pic=json.loads(self.get_pic(3)).get('data'),
            # 'try_extend[added_task][]'=Activity.echo_task(source),  # 根据活动来源,来判断用什么增值方式
            source=source, token=self.get_token(),
            shopId=value[0].get("sid"),
            shop_name=value[0].get("name"),
            Title=title,
            url_order=kwargs.get("order_url"),
            title_pic=json.loads(self.get_pic(0)).get('data'),
            search_pic=json.loads(self.get_pic(1)).get('data')
            # GrantNum = sum([yaml_data.get("data").get("try_extend_enter[%s][total]" % t) for t in
            #                 enter_type])  # 根据每个进店方式的份数计算总份数，进店方式是根据用户自己选择的
        )
        response = self.session.post(url, data=post_data, headers=header).text
        status = assert_result_dict(
            response, "vip商家" + self.uname + '发布精品试用 《' + title + "》 来源：" + source_cn + " ")
        if status:
            self.nums += 1
            self.tids.append(json.loads(response).get(
                "data").split('/')[-1])  # 发布成功的tid加到数组
            if self.nums == kwargs.get('num'):
                return
            # logger.info("提示：活动发布时间间隔在30s以上,发布成功之后请等待30s在发布下一个......")
            time.sleep(30)
        # self.pay(status,response)

    def release_activity(self):
        """
        发布活动
        :return:
        """
        source_list = self.echo_source()
        for source in source_list:
            order_url = get_order_url(highQualitySource(source).name)
            enter_type = self.echo_enter_type()
            self.release_basic(
                source=source,
                order_url=order_url,
                enter_type=enter_type,
                num=len(source_list))
        # loop = asyncio.get_event_loop()
        # loop.run_until_complete(self.pay)
        # asyncio.run(self.pay)
        # task_list = []
        # task = asyncio.create_task(self.release_basic(source=source,pd_sn=63,order_url=order_url,enter_type=enter_type))
        # task1 = asyncio.create_task(self.release_basic(source=source,pd_sn=63,order_url=order_url,enter_type=enter_type))
        # task_list.append(task)
        # task_list.append(task1)
        # results = asyncio.gather(*task_list)

    def pay_money(self):
        """
        支付活动款 [ 多进程处理 ]
        :return:
        """
        # for tid in self.tids:
        #     logger.info("支付tid：%s 活动款" % tid)
        #     pay = PayQuantity(self.session)
        #     pay.test_pay_quantity(tid)
        cpu_count = multiprocessing.cpu_count()
        # print('Cpu count:', cpu_count)
        # start = time.time()
        pool = multiprocessing.Pool(cpu_count)
        pool.map(self.pay.test_pay_quantity, self.tids)
        # end = time.time()
        # print('Cost time:', end - start)


def run():
    while True:
        seller_uname = input(u'请输入商家用户名(按Q|q返回上一目录): ')
        if seller_uname in ('q', 'Q'):
            break
        status = change_user_account_status(seller_uname)
        if not status:
            break
        activity = Activity(seller_uname)
        activity.release_activity()
        activity.pay_money()
        # task_list = []
        # task = asyncio.create_task(activity.release_activity())
        # task1 = asyncio.create_task(activity.release_activity())
        # task_list.append(task)
        # task_list.append(task1)
        # results = await asyncio.gather(*task_list)

# def main(fuc):
#     loop = asyncio.get_event_loop()
#     loop.run_until_complete(fuc)


if __name__ == "__main__":
    # activity = Activity('user0637')
    # main(activity.pay)
    # activity.release_activity()
    # asyncio.run(activity.main())
    run()
    # activity.pay_money()
